package com.ht.api.db.metadata;

import com.ht.api.db.Db;
import com.ht.api.db.DbList;
import com.ht.api.db.Entity;
import com.ht.api.db.SqlParser;
import com.ht.api.db.bean.DbSql;
import com.ht.api.db.exception.HtException;
import com.ht.api.db.util.HtUtil;

import cn.hutool.core.date.DateUtil;

/**
 * 数据库元数据管理器:表
 * @author asq
 * @createTime 2024年12月4日 14:01:29
 */
public class TableMetadataManager extends AbstractMetadataManager {
	/**
	 * 返回一个实例
	 * @return
	 */
	public static AbstractMetadataManager create() {
		return new TableMetadataManager();
	}

	@Override
	public DbList find(SqlParser sqlParser) {
		return SqlParser.create("db_table").where("code", sqlParser.getTable()).query();
	}

	@Override
	protected DbSql addData(Entity entity) {
		// 要返回的sql对象
		DbSql dbSql = new DbSql();
		
		// 表的各种信息
		String table = entity.getStr("code");
		String alias = entity.getStr("alias");
		String name = entity.getStr("name");
		String groupId = entity.getStr("group_id");
		String remark = entity.getStr("remark");
		String orderNum = entity.getStr("order_num");
		int tenant = entity.containsKey("tenant") ? entity.getInt("tenant") : 0;
		String sysTime = DateUtil.now();
		
		// table表插入一条数据
		String tableMainId = HtUtil.getId();
		dbSql.appendSql("insert into db_table(main_id,sys_time,sys_deleted,sys_creator,code,alias,name,tenant,group_id,remark,order_num)"
				+ " values (?,?,?,?,?,?,?,?,?,?,?);");
		dbSql.appendParam(tableMainId, sysTime, 1, 0, table, alias, name, tenant, groupId, remark, orderNum);
		entity.set("main_id", tableMainId);

		// 新增表的同时，写入4条column表数据，因为一个新表默认包含4列
		String columnSql = "insert into db_column(main_id,sys_time,sys_deleted,sys_creator,table_code,code,name,type,fun,"
				+ "default_value,primary_key,remark,order_num) values (?,?,?,?,?,?,?,?,?,?,?,?,?);";
		dbSql.appendSql(columnSql, columnSql, columnSql, columnSql);
		dbSql.appendParam(HtUtil.getId(), sysTime, 1, 0, table, "main_id", "main_id", "bigint", "KEY", null, 0, "", 0);
		dbSql.appendParam(HtUtil.getId(), sysTime, 1, 0, table, "sys_time", "sys_time", "varchar(19)", "MIN", null, 0, "", 0);
		dbSql.appendParam(HtUtil.getId(), sysTime, 1, 0, table, "sys_deleted", "sys_deleted", "int", "REPLACE_IF_NOT_NULL", null, 0, "", 0);
		dbSql.appendParam(HtUtil.getId(), sysTime, 1, 0, table, "sys_creator", "sys_creator", "int", "MIN", null, 0, "", 0);
		
		return dbSql;
	}

	@Override
	protected DbSql addSchema(Entity entity) {
		String tableCode = entity.getStr("code");
		String tableName = entity.getStr("name");
		StringBuilder tablesql = new StringBuilder();
		tablesql.append("CREATE TABLE IF NOT EXISTS `").append(tableCode).append("` ( ");
		tablesql.append("`main_id` bigint, ");
		tablesql.append("`sys_time` varchar(19) MIN , ");
		tablesql.append("`sys_deleted` int REPLACE_IF_NOT_NULL default '1',");
		tablesql.append("`sys_creator` bigint MIN ");
		tablesql.append(") ").append("AGGREGATE KEY(`main_id`)").append(" COMMENT '" + tableName + "' ")
				.append(" DISTRIBUTED BY HASH(`main_id`) BUCKETS 20 ")
				.append("PROPERTIES (\"group_commit_interval_ms\" = \"2000\");");
		
		return new DbSql().setSql(tablesql.toString());
	}

	@Override
	protected DbSql modifyData(Entity entity) {
		// 要返回的sql对象
		DbSql dbSql = new DbSql();
		
		// 修改前的对象
		Entity oldEntity = Db.createSqlParser("db_table").findById(sysDS, entity.get("main_id"));
		
		// 修改表
		dbSql.appendSql("update db_table set code=?,name=?,tenant=?,group_id=?,remark=?,order_num=? where main_id=?;");
		dbSql.appendParam(entity.getStr("code"), entity.getStr("name"), entity.getStr("tenant"), 
				entity.getStr("group_id"), entity.getStr("remark"), entity.getStr("order_num"), entity.getStr("main_id"));
		
		// 修改列
		dbSql.appendSql("update db_column set table_code=? where table_code=?;");
		dbSql.appendParam(entity.getStr("code"), oldEntity.getStr("code"));
		
		return dbSql;
	}

	@Override
	protected DbSql modifySchema(Entity entity) {
		if (!entity.containsKey("main_id")) {
			throw new HtException("json参数需要main_id字段~");
		}
		long mainId = entity.getLong("main_id");
		Entity oldEntity = Db.createSqlParser("db_table").findById(sysDS, mainId);
		if (oldEntity == null) {
			throw new HtException("main_id指定的表不存在:" + mainId);
		}
		String oldTableCode = oldEntity.getStr("code");
		String newTableCode = entity.getStr("code");
		if (oldTableCode.equals(newTableCode)) {
			// 表名没有实际变化时，不能执行ALTER TABLE语句，要报错
			return new DbSql();
		} else {
			String sql = String.format("ALTER TABLE `%s` RENAME `%s`;", oldTableCode, newTableCode);
			return new DbSql().setSql(sql);
		}
	}

	@Override
	protected DbSql delData(Entity entity) {
		DbSql dbSql = new DbSql();
		dbSql.appendSql("delete from db_table where code=?;");
		dbSql.appendSql("delete from db_column where table_code=?;");
		dbSql.appendParam(entity.getTable(), entity.getTable());
		return dbSql;
	}

	@Override
	protected DbSql delSchema(Entity entity) {
		return new DbSql().setSql(String.format("DROP TABLE if EXISTS `%s`;", entity.getTable()));
	}

	@Override
	protected boolean isTable() {
		return true;
	}
}
